package com.antwork.common.web.jsp;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;

public class TabTag extends AbstractTag {
	private static final long serialVersionUID = -143922948231757809L;
	private static HashMap<String, TabConfig> configMap = new HashMap();
	private String name;
	private String curTabType = "";

	private String tabKeepStr = "";
	private String contextPath;

	public void setName(String name) {
		this.name = name;
	}

	public String getCurTabType() {
		return this.curTabType;
	}

	public String getTabKeepStr() {
		return this.tabKeepStr;
	}

	public int doStartTag() throws JspException {
		HttpServletRequest request = (HttpServletRequest) this.pageContext
				.getRequest();
		this.contextPath = request.getContextPath();
		String uri = (String) request.getAttribute("uri");
		String t = (String) request.getAttribute("t");
		t = (t == null) ? "" : t;
		TabConfig config = (TabConfig) configMap.get(this.name);
		if (config == null) {
			try {
				config = loadConfig();
			} catch (Exception e) {
				throw new JspException(e);
			}
			configMap.put(this.name, config);
		}
		if (config == null) {
			return 6;
		}

		String baseURI = config.getUri();
		String simpleURI;
		if (baseURI != null)
			simpleURI = this.contextPath + baseURI;
		else {
			simpleURI = getOriginalURI(uri);
		}

		String[] tabType = config.getTabType();
		String[] displayName = config.getDisplayName();
		boolean isMatching = false;
		if (!t.equals("")) {
			for (int i = 0; i < tabType.length; ++i) {
				if (t.equals(tabType[i])) {
					isMatching = true;
				}
			}
			if (!isMatching) {
				t = "";
			}
		}
		this.curTabType = t;
		StringBuffer htmlStr = new StringBuffer("<div class=\"tabbable\">");
		htmlStr.append("<ul class=\"nav nav-tabs\">");
		for (int i = 0; i < tabType.length; ++i) {
			if ((t.equals("")) && (i == 0)) {
				htmlStr.append("<li class=\"active\"><a href=\"#\" data-toggle=\"tab\">"
						+ displayName[i] + "</a></li>");
			} else if (t.equals(tabType[i])) {
				htmlStr.append("<li class=\"active\"><a href=\"#\" data-toggle=\"tab\">"
						+ displayName[i] + "</a></li>");
			} else {
				String[] keep = config.getKeep();
				String keepStr = "";
				if (keep != null) {
					for (int j = 0; j < keep.length; ++j) {
						keepStr = keepStr + "&"
								+ getKeepParameterAndValue(uri, keep[j]);
					}
					if (!keepStr.equals("")) {
						keepStr = keepStr.substring(1);
					}
				}
				this.tabKeepStr = keepStr;
				String url;
				if (i == 0) {
					if (keepStr.equals(""))
						url = simpleURI;
					else
						url = simpleURI + "?" + keepStr;
				} else {
					if (keepStr.equals(""))
						url = simpleURI + "?t=" + tabType[i];
					else {
						url = simpleURI + "?t=" + tabType[i] + "&" + keepStr;
					}
				}

				htmlStr.append("<li><a href=\"" + url + "\">" + displayName[i]
						+ "</a></li>");
			}
		}

		htmlStr.append("</ul>");
		htmlStr.append("</div>");
		JspWriter writer = this.pageContext.getOut();
		try {
			writer.write(htmlStr.toString());
		} catch (IOException e) {
			throw new JspException(e);
		}

		return 1;
	}

	public int doEndTag() throws JspException {
		return 6;
	}

	private TabConfig loadConfig() throws Exception {
		String configName = "/page-" + this.name + ".properties";
		Properties prop = new Properties();
		try {
			InputStream is = TabConfig.class.getResourceAsStream(configName);
			// Properties prop = new Properties();
			prop.load(is);
		} catch (Throwable e) {
			throw new RuntimeException("table-config file cannot be load: "
					+ configName);
		}
		try {
			// Properties prop = null;
			TabConfig config = new TabConfig();
			String categoryStr = (String) prop.get("tab.category");
			if (categoryStr != null) {
				String[] cs = categoryStr.split(";");
				String[] tabType = new String[cs.length];
				String[] displayName = new String[cs.length];
				for (int i = 0; i < cs.length; ++i) {
					String[] c = cs[i].split("\\|");
					tabType[i] = c[0];
					displayName[i] = c[1];
				}
				config.setTabType(tabType);
				config.setDisplayName(displayName);
				String uri = prop.getProperty("tab.uri");
				config.setUri(uri);
			}
			String keepStr = (String) prop.get("tab.keep");
			if (keepStr != null) {
				String[] keep = keepStr.split(";");
				config.setKeep(keep);
			}
			return config;
		} catch (Exception e) {
			throw new Exception("Parse " + configName + " error! "
					+ e.getMessage());
		}
	}

	private String getOriginalURI(String uri) {
		uri = uri.replaceAll("#", "");
		if (uri.indexOf("?") != -1) {
			uri = uri.substring(0, uri.indexOf("?"));
		}
		return uri;
	}

	private String getKeepParameterAndValue(String uri, String param) {
		int index = uri.indexOf(param);
		if (index != -1) {
			String str = uri.substring(index, uri.length());
			String[] s = str.split("&");
			return s[0];
		}
		return "";
	}
}